package com.ming_za.odupdaterserver.core.utils;

import lombok.Getter;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/**
 * 二进制工具
 */
@Component
public class BinaryUtils {

    @Getter
    private static BinaryUtils instance;

    public BinaryUtils() {
        instance = this;
    }

    /**
     * 判断原数据是否包含item
     * @param origin 原数据
     * @param item 元素
     */
    public boolean include(long origin,long item){
        return (origin & item) == item;
    }

    /**
     * 判断原数据是否有一位与item相同
     * @param origin 原数据
     * @param item 元素
     */
    public boolean sameOne(long origin,long item){
        return (origin & item) > 0;
    }

    /**
     * 判断原数据是否包含item
     * @param origin 原数据
     * @param item 元素
     */
    public boolean include(int origin,int item){
        return (origin & item) == item;
    }

    /**
     * 判断原数据是否有一位与item相同
     * @param origin 原数据
     * @param item 元素
     */
    public boolean sameOne(int origin,int item){
        return (origin & item) > 0;
    }

    /**
     * 判断原数据是否包含item
     * @param origin 原数据
     * @param item 元素
     */
    public boolean include(byte origin,byte item){
        return (origin & item) == item;
    }

    /**
     * 判断原数据是否有一位与item相同
     * @param origin 原数据
     * @param item 元素
     */
    public boolean sameOne(byte origin,byte item){
        return (origin & item) > 0;
    }

    /**
     * 判断数据是否只存在一位为1，即数据最高位与最低位相同
     * @param data 数据
     */
    public boolean onlyOneBit(long data){
        return Long.highestOneBit(data) == Long.lowestOneBit(data);
    }

    /**
     * 判断数据是否只存在一位为1，即数据最高位与最低位相同
     * @param data 数据
     */
    public boolean onlyOneBit(int data){
        return Integer.highestOneBit(data) == Integer.lowestOneBit(data);
    }

    /**
     * 判断数据是否只存在一位为1，即数据最高位与最低位相同
     * @param data 数据
     */
    public boolean onlyOneBit(byte data){
        return Integer.highestOneBit(data) == Integer.lowestOneBit(data);
    }

    /**
     * 将long类型按bit拆分
     * @param l 需要拆分的值
     * @return 拆分后的long {@link java.util.HashSet}
     */
    public Set<Long> splitLongBit(long l){
        Set<Long> set = new HashSet<>();
        if (l == 0){
            return set;
        }
        for (int i = 0;i < 64;i++){
            if ((l & 1) == 1){
                set.add(1L << i);
            }
            l >>= 1;
        }
        return set;
    }

}
